// Learned:
// 1.accept和connect的返回值意义是不同的！connect的返回值仅代表成功与否；read和write的fd是socket获取的fd！
// 2.改为短服务后，要不断地循环获取连接！
// 3.重连机制的设定！
#include "log.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <string.h>
#include <unistd.h>

using std::cin;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        exit(0);
    }

    sockaddr_in server;
    int port = stoi(argv[2]);

    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(argv[1]);
    char recvbuff[1024];
    int socketfd;
    while (1)
    {
        socketfd = socket(AF_INET, SOCK_STREAM, 0);
        if (socketfd < 0)
        {
            log(Fatal, "socket error, errno is %d, error messsage: %s", errno, strerror(errno));
            exit(1);
        }        

        //循环获取链接（模拟重连）
        int cnt = 5;
        do
        {
            int res = connect(socketfd, (sockaddr *)&server, sizeof(server));
            if (res < 0)
            {
                cout << "trying to reconnect... -- " << cnt << endl;
                sleep(1);                
            }  
            else
            {
                break;
            }      
        } while (cnt--);
        if(cnt == 0)
        {
            log(Error, "connect error, errno is %d, error message: %s", errno, strerror(errno));
            exit(-1);
        }
        

        string msg;
        cout << "Please Enter@ " ;
        getline(cin, msg);
        if (write(socketfd, msg.c_str(), msg.size()) < 0)
        {
            log(Error, "write error, errno is %d, error msg is %s", errno, strerror(errno));
            exit(-1);
        }

        memset(recvbuff,0,sizeof(recvbuff));
        if (read(socketfd, recvbuff, 1024) < 0)
        {
            log(Error, "read error, errno is %d, error msg is %s", errno, strerror(errno));
            exit(-1);
        }
        cout << recvbuff << endl;

        close(socketfd);
    }
    
    return 0;
}